const app = getApp()

function inArray(arr, key, val) {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i][key] === val) {
            return i;
        }
    }
    return -1;
}

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        function (bit) {
            return ('00' + bit.toString(16)).slice(-2)
        }
    )
    return hexArr.join('');
}

// 字符串转ArrayBuffer
function stringToArrayBuffer(str) {
    let buffer = new ArrayBuffer(str.length)
    let dataView = new DataView(buffer)
    for (let i = 0; i < str.length; i++) {
        dataView.setUint8(i, str.charCodeAt(i))
    }
    return buffer
}

Page({
    data: {
        devices: [],
        connected: false,
        chs: [],
        ssid: "",
        password: "",
        blename: "ble-config",
        isshow: false,
        dis_btn: false
    },
    inputSSID: function (e) { //输入WiFi名称
        this.setData({
            ssid: e.detail.value
        })
    },
    inputPWD: function (e) { //输入WiFi密码 
        this.setData({
            password: e.detail.value
        })
    },
    changanshow: function (e) {
        this.setData({
            isshow: !this.data.isshow,
            dis_btn: !this.data.dis_btn,
            devices: []
        })
    },
    kaishilianjie: function (e) { //点击连接按钮------------------------------------111111111
        if (this.data.ssid == "" || this.data.password == "") {
            wx.showToast({
                title: '请输入WiFi名称和密码',
                icon: 'error',
                duration: 2000
            })
            return
        }
        this.setData({
            dis_btn: true
        })
        this.openBluetoothAdapter()
    },
    onLoad: function (options) { //页面启动时获取WiFi信息
        var that = this
        wx.startWifi({
            success(res) {
                console.log(res)
                wx.getConnectedWifi({
                    success(res) {
                        console.log(res)
                        if (res.errCode == 0) {
                            console.log(res.wifi.SSID)
                            that.setData({
                                ssid: res.wifi.SSID
                            })
                        }
                    }
                })
            }
        })
    },

    openBluetoothAdapter() { //点击开始扫描按钮---------------------------222222222222222222222
        console.log("开始扫描")
        if (!this.data.isshow) {
            this.showMSG("正在开启蓝牙")
        }
        var that = this
        that.setData({
            devices: []
        })
        wx.openBluetoothAdapter({
            success: (res) => {
                console.log('openBluetoothAdapter success', res)
                that.startBluetoothDevicesDiscovery()
            },
            fail: (res) => {
                console.log(res)
                //that.getBluetoothAdapterState()
                if (res.errCode === 10001) {
                    wx.showToast({
                        title: '请打开蓝牙',
                        icon: 'error',
                        duration: 2000
                    })
                    that.setData({
                        dis_btn: false
                    })
                    wx.onBluetoothAdapterStateChange(function (res) {
                        console.log('onBluetoothAdapterStateChange', res)
                        if (res.available) {
                            that.startBluetoothDevicesDiscovery()
                        }
                    })
                } else {
                    console.log(res)
                    wx.showToast({
                        title: "蓝牙连接失败\n" + res.errCode,
                        icon: 'error',
                        duration: 2000
                    })
                    that.setData({
                        dis_btn: false
                    })
                }
            }
        })
    },
    getBluetoothAdapterState() { //获取蓝牙状态，未用
        wx.getBluetoothAdapterState({
            success: (res) => {
                console.log('getBluetoothAdapterState', res)
                if (res.discovering) {
                    this.onBluetoothDeviceFound()
                } else if (res.available) {
                    this.startBluetoothDevicesDiscovery()
                }
            }
        })
    },
    startBluetoothDevicesDiscovery() { //开始搜寻附近的蓝牙外围设备------------------3333333333333333
        if (this._discoveryStarted) {
            return
        }
        if (!this.data.isshow) {
            this.showMSG("正在搜索设备")
        }
        this._discoveryStarted = true
        wx.startBluetoothDevicesDiscovery({
            allowDuplicatesKey: true,
            success: (res) => {
                console.log('startBluetoothDevicesDiscovery success', res)
                this.onBluetoothDeviceFound()
            },
        })
    },
    stopBluetoothDevicesDiscovery() {
        console.log("停止扫描")
        wx.stopBluetoothDevicesDiscovery()
    },
    onBluetoothDeviceFound() { //当发现蓝牙设备----------------------------44444444444444444444
        wx.onBluetoothDeviceFound((res) => {
            res.devices.forEach(device => {
                if (!device.name && !device.localName) {
                    return
                }

                const foundDevices = this.data.devices
                const idx = inArray(foundDevices, 'deviceId', device.deviceId)
                const data = {}
                if (idx === -1) {
                    data[`devices[${foundDevices.length}]`] = device
                } else {
                    data[`devices[${idx}]`] = device
                }
                console.log(data)
                this.setData(data)
                if (!this.data.isshow) {
                    /**如果发现的蓝牙设备名称与默认名称相同，停止扫描，开始连接 */
                    console.log(device.name, device.deviceId)
                    if (device.name == this.data.blename || device.localName == this.data.blename) {
                        this.stopBluetoothDevicesDiscovery() //当搜索到指定设备就停止继续搜索
                        var drv = {
                            "currentTarget": {
                                "dataset": {
                                    "deviceId": device.deviceId,
                                    "name": device.name || device.localName
                                }
                            }
                        }
                        this.createBLEConnection(drv)
                    }
                }
            })
        })
    },
    createBLEConnection(e) { //点击搜索到的蓝牙条目后开始连接-----------55555555555555555555555
        console.log(e)
        if (!this.data.isshow) {
            this.showMSG("正在连接设备")
        }
        const ds = e.currentTarget.dataset
        const deviceId = ds.deviceId
        const name = ds.name
        wx.createBLEConnection({
            deviceId,
            success: (res) => {
                this.setData({
                    connected: true,
                    name,
                    deviceId,
                })
                this.getBLEDeviceServices(deviceId) //获取蓝牙设备所支持的服务
            }
        })
        this.stopBluetoothDevicesDiscovery() //当与蓝牙设备连接后就停止扫描
    },
    closeBLEConnection() { //点击按钮 断开蓝牙连接--------------------------999999999999999999
        if (!this.data.isshow) {
            this.showMSG("正在断开蓝牙连接")
        }
        wx.closeBLEConnection({
            deviceId: this.data.deviceId
        })
        this.setData({
            connected: false,
            chs: [],
            canWrite: false,
        })
    },
    getBLEDeviceServices(deviceId) { //获取蓝牙设备所支持的服务------------66666666666666666
        if (!this.data.isshow) {
            this.showMSG("获取蓝牙服务")
        }
        wx.getBLEDeviceServices({
            deviceId,
            success: (res) => {
                for (let i = 0; i < res.services.length; i++) {
                    if (res.services[i].isPrimary) {
                        this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
                        return
                    }
                }
            }
        })
    },
    getBLEDeviceCharacteristics(deviceId, serviceId) { //获取蓝牙低功耗设备某个服务中所有特征-7777777777777777777777777777777777777
        wx.getBLEDeviceCharacteristics({
            deviceId,
            serviceId,
            success: (res) => {
                console.log('getBLEDeviceCharacteristics success', res.characteristics)
                for (let i = 0; i < res.characteristics.length; i++) {
                    let item = res.characteristics[i]
                    if (item.properties.read) {
                        wx.readBLECharacteristicValue({
                            deviceId,
                            serviceId,
                            characteristicId: item.uuid,
                        })
                    }
                    if (item.properties.write) {
                        this.setData({
                            canWrite: true
                        })
                        this._deviceId = deviceId
                        this._serviceId = serviceId
                        this._characteristicId = item.uuid
                        if (!this.data.isshow) {
                            this.writeBLECharacteristicValue() //向蓝牙设备发送WiFi信息
                        }
                    }
                    if (item.properties.notify || item.properties.indicate) {
                        wx.notifyBLECharacteristicValueChange({
                            deviceId,
                            serviceId,
                            characteristicId: item.uuid,
                            state: true,
                        })
                    }
                }
            },
            fail(res) {
                console.error('getBLEDeviceCharacteristics', res)
            }
        })
        wx.onBLECharacteristicValueChange((characteristic) => {
            //监听蓝牙低功耗设备的特征值变化事件。
            const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
            const data = {}
            if (idx === -1) {
                data[`chs[${this.data.chs.length}]`] = {
                    uuid: characteristic.characteristicId,
                    value: ab2hex(characteristic.value)
                }
            } else {
                data[`chs[${idx}]`] = {
                    uuid: characteristic.characteristicId,
                    value: ab2hex(characteristic.value)
                }
            }
            this.setData(data)
        })
    },
    writeBLECharacteristicValue() { //向蓝牙设备发送WiFi信息-------------8888888888888888888

        if (!this.data.canWrite) {
            this.setData({
                dis_btn: false
            })
            wx.showToast({
                title: '不能写入数据',
                icon: 'none'
            })
            return
        }
        if (!this.data.isshow) {
            this.showMSG("发送WiFi信息")
        }
        // 发送SSID
        let ssidBuffer = stringToArrayBuffer("ssid_" + this.data.ssid)
        wx.writeBLECharacteristicValue({
            deviceId: this._deviceId,
            serviceId: this._serviceId,
            characteristicId: this._characteristicId,
            value: ssidBuffer,
            success: (res) => {
                console.log('write ssid success', res)
            },
            fail: (res) => {
                console.error('write ssid fail', res)
            }
        })

        // 发送密码
        let passwordBuffer = stringToArrayBuffer("pswd_" + this.data.password)
        wx.writeBLECharacteristicValue({
            deviceId: this._deviceId,
            serviceId: this._serviceId,
            characteristicId: this._characteristicId,
            value: passwordBuffer,
            success: (res) => {
                console.log('write password success', res)
            },
            fail: (res) => {
                console.error('write password fail', res)
            },
            complete: (res) => {
                if (!this.data.isshow) {
                    this.closeBLEConnection()
                    this.closeBluetoothAdapter()
                }
            }
        })
    },
    closeBluetoothAdapter() { //关闭蓝牙模块--------------------------------10 10 10 10 10 10
        console.log("结束")
        if (!this.data.isshow) {
            this.showMSG("正在关闭蓝牙")
        }
        wx.closeBluetoothAdapter()
        this._discoveryStarted = false
        if (!this.data.isshow) {
            setTimeout(function () {
                wx.hideLoading()
            }, 1000)
            this.setData({
                dis_btn: false
            })
        }
    },
    showMSG(s) {
        wx.showLoading({
            title: s,
            mask: true
        })
    }
})